package org.nox.helloseries.server.connector.bdd.impl;

import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.nox.helloseries.configuration.CustomConfiguration;
import org.nox.helloseries.configuration.CustomConfigurationKey;
import org.nox.helloseries.domain.NomTracker;
import org.nox.helloseries.domain.Tracker;
import org.nox.helloseries.server.connector.bdd.CookieConnector;
import org.nox.helloseries.server.connector.bdd.domain.BrowserCookieTable;
import org.nox.helloseries.server.services.browser.domain.Navigateur;
import org.nox.helloseries.server.utils.ext.BrowserControl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DefaultCookieConnector implements CookieConnector
{
    private static final Logger LOG = LoggerFactory.getLogger( DefaultCookieConnector.class );

    // WINDOWS
    private static final String FIREFOX_WIN_PATH = "\\Mozilla\\Firefox\\Profiles\\";

    private static final String CHROME_WIN_PATH = "\\Local Settings\\Application Data\\Google\\Chrome\\User Data\\Default\\";

    // LINUX
    private static final String FIREFOX_UNIX_PATH = "/.mozilla/firefox";

    private static final String FIREFOX_COOKIE_FILENAME = "cookies.sqlite";

    private static final String CHROME_COOKIE_FILENAME = "Cookies";

    public DefaultCookieConnector()
    {
    }

    public Connection getConnection( String path )
    {
        try
        {
            Class.forName( "org.sqlite.JDBC" );
            return DriverManager.getConnection( "jdbc:sqlite:" + path );
        }
        catch ( ClassNotFoundException e )
        {
            LOG.error( e.getMessage() );
        }
        catch ( SQLException e )
        {
            LOG.error( e.getMessage() );
        }
        return null;
    }

    @Override
    public Map<String, String> searchCookie( Tracker tracker, Navigateur navigateur )
    {
        String cookiePath = getCookieFilePath( navigateur );
        if ( StringUtils.isNotEmpty( cookiePath ) && FileUtils.getFile( cookiePath ).exists() )
        {
            switch ( tracker.getNomTracker() )
            {
            case FRENCHTORRENTDB:
            case TORRENT411:
                return searchCookieInBrowserDB( cookiePath, tracker.getNomTracker(), navigateur.getBrowserCookieTable() );
            default:
                break;
            }
        }
        else
        {
            LOG.error( "Fichier cookie introuvable (navigateur={} - path={}", navigateur, cookiePath );
        }

        return null;
    }

    /**
     * Retour les cookies trouvés pour le tracker FTDB
     * 
     * @param tracker
     * @param browserCookieTable
     * @return
     */
    private Map<String, String> searchCookieInBrowserDB( String cookieFilePath, NomTracker nomTracker, BrowserCookieTable browserCookieTable )
    {
        LOG.info( "Récupération des cookies pour le tracker " + nomTracker );
        // Retour
        Map<String, String> cookies = new HashMap<>();

        Connection con = getConnection( cookieFilePath );
        if ( con != null )
        {
            try (Statement statement = con.createStatement())
            {
                String query = "SELECT * FROM " + browserCookieTable.getTableName() + " WHERE " + browserCookieTable.getHostColumnName() + " = '" + nomTracker.getCookieValue()
                    + "' and name NOT LIKE '%_utm%'";

                LOG.info( "Requête lancée sur la BDD sqlite des cookies de " + nomTracker + " : " + query );

                ResultSet results = statement.executeQuery( query );

                while ( results.next() )
                {
                    cookies.put( results.getString( "name" ), results.getString( "value" ) );
                }
            }
            catch ( SQLException e )
            {
                LOG.error( "Erreur de connexion à la BDD de cookies " + e.getMessage() );
            }

            LOG.info( "Liste des cookies : " + cookies );
        }

        return cookies;
    }

    private String getCookieFilePath( Navigateur navigateur )
    {
        // Répertoire des Cookies de Firefox
        switch ( navigateur )
        {
        case FIREFOX:
            String firefoxCookieLocation = "";

            if ( BrowserControl.isWindowsPlatform() )
            {
                firefoxCookieLocation = System.getenv( "APPDATA" ) + FIREFOX_WIN_PATH;
            }
            else
            {
                firefoxCookieLocation = CustomConfiguration.get().getString( CustomConfigurationKey.COOKIE_HOME_UNIX ) + "/" + FIREFOX_UNIX_PATH;
            }
            File f = new File( firefoxCookieLocation );
            if ( f.listFiles() != null )
            {
                for ( File defaultFolder : f.listFiles() )
                {

                    if ( defaultFolder.getPath().contains( "default" ) )
                    {
                        firefoxCookieLocation = defaultFolder.getPath();
                    }
                }
            }
            else
            {
                LOG.error( "Firefox non présent sur le système" );
            }
            firefoxCookieLocation += "\\" + FIREFOX_COOKIE_FILENAME;
            firefoxCookieLocation = FilenameUtils.separatorsToSystem( firefoxCookieLocation );
            LOG.debug( "firefoxCookieLocation={}", firefoxCookieLocation );
            return firefoxCookieLocation;
        case CHROME:
            if ( BrowserControl.isWindowsPlatform() )
            {
                // Répertoire des Cookies de chrome
                String chromeCookieLocation = FilenameUtils.separatorsToSystem( System.getenv( "HOMEDRIVE" ) + System.getenv( "HOMEPATH" ) + CHROME_WIN_PATH + CHROME_COOKIE_FILENAME );
                LOG.debug( "chromeCookieLocation={}", chromeCookieLocation );
                return chromeCookieLocation;
            }
            break;
        }
        return null;
    }
}
